package com.fsnbigdata.service.impl;

import com.fsnbigdata.domain.Log;
import com.fsnbigdata.domain.ZhExpert;
import com.fsnbigdata.repository.LogRepository;
import com.fsnbigdata.repository.ZhExpertRepository;
import com.fsnbigdata.service.api.LogService;
import com.fsnbigdata.service.api.ZhExpertService;
import com.fsnbigdata.util.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.*;
import java.util.*;

/**
 * @Author:
 * @Date: Created in 19:07 2018/9/29
 * @Modified By:
 */

@Service
public class LogServiceImpl implements LogService{
    
    @Autowired
    LogRepository logRepository;
    
    @Override
    public Log findById(Long id) {
        return logRepository.findOne(id);
    }
    
    @Override
    public Log save(Log log) {
        return logRepository.save(log);
    }

    @Override
    public List<Log> findAllByTime(String startTime, String endTime,String type,String key) {
        if(!(startTime==null||"".equals( startTime )||endTime==null||"".equals( endTime ))){
            return logRepository.findAllByTime(Long.parseLong(startTime),Long.parseLong(endTime),type,key);
        }
        return logRepository.findAllByTypeAndKey(type,key);
    }

    @Override
    public List<Log> findAll() {
        return logRepository.findAll();
    }
    
    @Override
    public void deleteOne(Long id) {
        logRepository.delete(id);
    }
    
    @Override
    public void delete(Iterable<Long> ids) {
        List<Log> logs = logRepository.findAll(ids);
        logRepository.deleteInBatch(logs);
    }
    
    @Override
    public Log update(Log log) {
        return logRepository.save(log);
    }
    
    public Page<Log> findByPageAndSize(String startTime,String endTime, String creator,String genre,String description,Pageable pageable){
        Specification<Log> specification = new Specification<Log>() {
            @Override
            public Predicate toPredicate(Root<Log> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {

                Path<String> _creator = root.get("username");
                Path<String> _genre = root.get("genre");
                Path<String> _description = root.get("description");
                List<Predicate> list = new ArrayList <Predicate>();

                if(!(startTime==null||"".equals( startTime )||endTime==null||"".equals( endTime ))){
                    Date start = new Date(Long.parseLong(startTime));
                    Date end = new Date(Long.parseLong(endTime));
                    list.add( criteriaBuilder.and(criteriaBuilder.between(root.get("createTime"),start,end)));
                }
                if(!(creator==null||"".equals( creator))){
                    list.add( criteriaBuilder.equal( _creator,creator));
                }
                if(!(genre==null||"".equals( genre))){
                    list.add( criteriaBuilder.equal( _genre,genre));
                }
                if(!(description==null||"".equals( description))){
                    list.add( criteriaBuilder.like(_description, "%" + description + "%"));
                }
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and( list.toArray(p) );

            }
        };
        return logRepository.findAll(specification,pageable);
    }
    
    @Override
    public List<Log> findAllByType(String type) {
        return logRepository.findAllByType(type);
    }

    @Override
    public List queryList(String type, Pageable pageable) {
        List list = new ArrayList(  );
        list.add( logRepository.getCount(type) );
        list.add( logRepository.queryList( type,pageable ) );
        return list;
    }

    /**
     * 统计一周的登录次数
     * @param type 日志类型
     * @param name 用户名称（用于排除，即不查含有该名称的数据）
     * @param oldTime 上一周的时间戳
     * @param nowTime 当前的时间戳
     * @return
     */
    @Override
    public Long getCount(String type, String name, long oldTime, long nowTime) {
        return logRepository.getCount(type,name,oldTime,nowTime);
    }

    /**
     * 查询当前日期之前某一时间段内的数据列表
     * @param nowTime
     * @param beforeTime
     * @param genre
     * @return
     */
    @Override
    public List<Log> findAllByBeforeTime(long nowTime, long beforeTime, String genre) {
        return logRepository.findAllByBeforeTime(nowTime,beforeTime,genre);
    }

    @Override
    public List chartCount(String status, String startTime, String endTime, String description, String creator) {
        Date date = DateUtil.getEndOfDay(new Date());
        Calendar c = Calendar.getInstance();
        if("0".equals(status)){
            if(startTime==null||"".equals( startTime )||endTime==null||"".equals( endTime )){
                Log log  = logRepository.queryAllLimitOne();
                startTime = DateUtil.getEndOfDay(log.getCreateTime()).getTime()+"";
                endTime = DateUtil.getEndOfDay(new Date()).getTime()+"";
            }
        }
        if (!(status == null || "".equals(status) || "0".equals(status))) {
            switch (status) {
                //近一周
                case "1":
                    c.setTime(date);
                    c.add(Calendar.DAY_OF_WEEK, - 6);
                    startTime = c.getTime().getTime()+"";
                    endTime = date.getTime()+"";
                    break;
                //近一月
                case "2":
                    c.setTime(date);
                    c.add(Calendar.DAY_OF_WEEK, - 27);
                    startTime = c.getTime().getTime()+"";
                    endTime = date.getTime()+"";
                    break;
                //近三月
                case "3":
                    c.setTime(date);
                    c.add(Calendar.DAY_OF_WEEK, - (3*28-1));
                    startTime = c.getTime().getTime()+"";
                    endTime = date.getTime()+"";
                    break;
                //近半年
                case "4":
                    c.setTime(date);
                    c.add(Calendar.DAY_OF_WEEK, - (6*28-1));
                    startTime = c.getTime().getTime()+"";
                    endTime = date.getTime()+"";
                    break;
                //近一年
                case "5":
                    c.setTime(date);
                    c.add(Calendar.DAY_OF_WEEK, - (12*28-1));
                    startTime = c.getTime().getTime()+"";
                    endTime = date.getTime()+"";
                    break;
            }
        }
        List<Map> list = DateUtil.getTime(startTime,endTime);
        List maps = new ArrayList<>();
        List x = new ArrayList();
        List y = new ArrayList();
        List normal = new ArrayList();
        List abnormal = new ArrayList();
        List warning = new ArrayList();
        for(Map map:list){
            Long sTime = ((Long)map.get("startTime"))/1000;
            Long eTime = ((Long)map.get("endTime"))/1000;
            String formatDate = map.get("formatDate").toString();
            normal.add(logRepository.queryCount(sTime,eTime,"0",description,creator));
            abnormal.add(logRepository.queryCount(sTime,eTime,"1",description,creator));
            warning.add(logRepository.queryCount(sTime,eTime,"2",description,creator));
            x.add(formatDate);
        }
        Map m = new HashMap();
        m.put("normal",normal);
        m.put("abnormal",abnormal);
        m.put("warning",warning);
        y.add(m);
        maps.add(x);
        maps.add(y);
        return maps;
    }

}
